package com.quikin.web.controller.html;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Locale;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

import com.quikin.common.util.IConstants;
import com.quikin.persistence.jpa.util.QuikinPLException;
import com.quikin.web.controller.util.ResponseHeader;
import com.von.platform.dk.util.PDKException;
import com.von.platform.dk.util.PDKRuntimeException;
import com.von.platform.impl.openjpa.std.EntityManagerContanier;
import com.von.platform.thridparty.spring.mvc.AbstractController;

@Controller
public class HtmlController extends AbstractController {
    private static final Logger logger = Logger.getLogger(HtmlController.class);

    @Override
    protected String getErrorViewName() {
        return "html/common/error";
    }

    @Override
    protected String getExceptionStatus() {
        return ResponseHeader.EXCEPTION.name();
    }

    @Override
    protected void createPageInfo(String status, String responseCode, String description, ModelAndView mav) {
        mav.addObject(ResponseHeader.responseStatus.name(),status);
        mav.addObject(ResponseHeader.responseCode.name(), responseCode);
        mav.addObject(ResponseHeader.responseDescription.name(), description);    
    }

    @ExceptionHandler (QuikinPLException.class)
    public ModelAndView handleQuikinException(HttpServletRequest req,  HttpServletResponse resp, Exception ex, Locale locale) {
        logger.error("Exception",ex);
        ModelAndView mav = new ModelAndView();
        createPageInfo(getExceptionStatus(), ex.getMessage(), getExceptionLocalizedMessage(ex, locale), mav);
        if (logger.isDebugEnabled()) {
            StringWriter sw = new StringWriter();
            ex.printStackTrace(new PrintWriter(sw));
            mav.addObject(ResponseHeader.responseDebugInfo.name(), sw.toString());
        }
        mav.setViewName(getErrorViewName());
        return mav;
    }
    
    @ExceptionHandler (Exception.class)
    public ModelAndView handleTransactionException(HttpServletRequest req,  HttpServletResponse resp, Exception ex, Locale locale) {
        logger.error("Exception",ex);
        try {
            EntityManagerContanier.getInstance().getCurrentEntityManager(IConstants._PERSISTENCE_UNIT_NAME).getTransaction().setRollbackOnly();
        } catch (Exception e) {
            logger.fatal("Cannot rollback transaction",e);
        }
        ModelAndView mav = new ModelAndView();
        createPageInfo(getExceptionStatus(), ex.getMessage(), getExceptionLocalizedMessage(ex, locale), mav);
        if (logger.isDebugEnabled()) {
            StringWriter sw = new StringWriter();
            ex.printStackTrace(new PrintWriter(sw));
            mav.addObject(ResponseHeader.responseDebugInfo.name(), sw.toString());
        }
        mav.setViewName(getErrorViewName());
        return mav;
    }

    private String getExceptionLocalizedMessage(Exception ex, Locale locale) {
        if (ex instanceof PDKException) {
            return ((PDKException) ex).getLocalizedMessage(locale);
        }
        if (ex instanceof PDKRuntimeException) {
            return ((PDKRuntimeException) ex).getLocalizedMessage(locale);
        }
        return ex.getLocalizedMessage();
    }
    
}
